-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve error handling and logic #58
Improve error handling and logic #58
Conversation
Looks good @mcaskill are you still working on this? |
Thanks. Unfortunately, at this time, I won't be able to continue/finish work on this feature. If you or someone else wants to take over, I can add them to the branch.
|
5b3a2d9
to
05d1612
Compare
Use `http_build_query()` to improve readability and reduce risk of errors.
Use GET instead of POST to better match the verb to the request and for consistency between downloaders.
Changed: - Throw `InvalidArgumentException` instead of `UnexpectedValueException` when dealing with an unsupported package in Ninja Forms, PublishPress Pro, and WPML. - Throw `UnexpectedValueException` if the decoded/unserialized API response is not an array. - Improved messages to clarify errors from API. - Fixed and improved PHPDoc tags to document exceptions.
Changed: - Use booleans intead of integers for cURL options. - Compile URL in GET request earlier to organize cURL options similarly to POST request.
Changed: - Added protected method `request()` to aggregate the execution of the request, handling of the response, and closing of the cURL handler. - Added cURL option `CURLOPT_FAILONERROR` to fail if the response is >= 400. - Throw `RuntimeException ` if the request failed. - Fixed and improved PHPDoc tags.
Changed: - Replaced `getDownloadUrl()` in EDD plugins with a new protected method `getDownloadUrlFromApi()` that only handles the request for the download URL response object. - Replaced `extractDownloadUrl()` with `getDownloadUrl()` in `AbstractEddPlugin` that retrieves the response to parse from the plugin's `getDownloadUrlFromApi()`. - Wrapped requests with `Http` in a try/catch to intercept cURL exceptions and wrap them in a plugin-aware exception.
05d1612
to
cee1cf5
Compare
I've updated the pull request title and description to reflect the latest state of proposed changes. The initially proposed changes for Gravity Forms will be resubmitted as its own pull request once we've figured out this request. |
A URL is necessary for requests.
Changed: - Removed extraneous property descriptions. - Rephrased description of `$slug` property to be more specific. - Added missing `$slug` method parameter.
Amends cee1cf5 Accidentally reverted back from GET to POST.
Decoupled API URL and API URL query parameters from its HTTP query building and URL concatenation, and HTTP request call. This allows the base URL and query parameters to be more readable from their final concatenated URL or HTTP request call.
This ensures compatibility with the classes' `$version` property being potentially empty, presuming a request for the latest version.
To reduce repetition, and risk of mistakes, when formatting the plugin's Composer package name. The package name is used in the messaging of most exceptions thrown. Storing vendor name as a namespace
Changed: - Moved shared cURL options to `request()` method. - Catch any exception from `Http` requests.
Separated JSON decoding error handling from HTTP request/response error handling. By using `json_last_error()`, we can provide a more precise error for end users as opposed to just checking if its an array. Output a truncated excerpt of the response body if JSON decoding fails to give a hint of what the issue might be.
I found some time to do some further testing and improvements. I think it should be functional enough. If people can test, that would be appreciated. |
c736634
to
03771dd
Compare
Separated unserialization error handling from HTTP request/response error handling. Wrapped unserialization in try/catch to intercept any throwables from unexpected objects in their unserialization handlers. Gravity Forms is supposed to return an associative array but could be compromised. Output a truncated excerpt of the response body if unserialization fails to give a hint of what the issue might be. Ideally, add an error handler to catch the PHP notice that is raised by `unserialize()`.
03771dd
to
ab73a24
Compare
From 'mcaskill/feature/refactor-http-class': Improve error handling and logic
Checklist
Draft 2 — 2023-03-15
Description
Follow-up to #52 and alternative to the initial draft (see below).
Primary focus is improving error handling by validating the response from cURL requests, validating the decoded/unserialized response bodies, and simplifying the logic between plugins.
How has this been tested?
I'm testing this on client projects that use ACF Pro, ACF Extended Pro, PublishPress Pro, Gravity Forms, Polylang Pro, and WPML.
Screenshots
Types of changes
http_build_query()
to improve readability and reduce risk of mistakes.GET
instead ofPOST
to better match the verb of the request and for consistency between the other downloader. Both Gravity Forms' API and Easy Digital Downloads' API supportGET
requests.InvalidArgumentException
instead ofUnexpectedValueException
when dealing with an unsupported package.UnexpectedValueException
if the decoded/unserialized API response is not an array.getDownloadUrl()
with a new protected methodgetDownloadUrlFromApi()
that only handles the request for the download URL response object.AbstractEddPlugin
:extractDownloadUrl()
withgetDownloadUrl()
that retrieves the response to parse from the plugin'sgetDownloadUrlFromApi()
.Http
in a try/catch to intercept cURL exceptions and wrap them in a plugin-aware exception.Http
:request()
to aggregate the execution of the request, handling of the response, and closing of the cURL handler.CURLOPT_FAILONERROR
to fail if the response is >= 400.RuntimeException
if the request failed.Draft 1 — 2023-03-07
Description
Follow-up to #52.
Fixed the PSR-4 file name for
Wpml
class, for the sake of testing.Improve checks on HTTP response. Check if status code is OK (200) and if the body is an array, throw exceptions if not with an excerpt of the response body for aid with debugging.
Expanding upon #47, improved Gravity Forms to check if download version matches the package's version with support for either available download: the "main version" (
download_url
) or the "latest version" (download_url_latest
). For example:version
:2.7.2
(PARADIGM.MAJOR.MINOR
)version_latest
:2.7.2.1
(PARADIGM.MAJOR.MINOR.PATCH
)As of 2023-03-08, this code sort of works but is not completely tested/vetted, nor is it the best design, and some of it should be split into their own pull requests.
If we drop support for Composer 1, a lot of this proposed code can be simplified to take advantage of Composer 2's utilities.
I'm open to comments, suggestions, and contributions.
How has this been tested?
I'm testing this on client projects that use ACF Pro,
ACF Extended Pro,PublishPress Pro, Gravity Forms, Polylang Pro, and WPML.Types of changes
http_build_query()
to improve readability and reduce risk of mistakes.GET
instead ofPOST
to better match the verb of the request and for consistency between the other downloader. Both Gravity Forms' API and Easy Digital Downloads' API supportGET
requests.Http
class to store last response body and headers, allow parsing of body through callback, and finding of status code and message (based on Composer 2'sResponse
,RemoteFileSystem
, andHttpDownloader
).Semver
to check Gravity Forms versions and throw an exception if we download the incorrect version.